package com.ruoyi.framework.web.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.Condition;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.wq.domain.WqVote;
import com.ruoyi.wq.domain.vo.WqVoteVO;
import com.ruoyi.wq.service.IWqVoteService;
import com.ruoyi.wx.domain.WxMaMsgForm;
import com.ruoyi.wx.service.WxMsgService;

import cn.hutool.core.date.DateUtil;

@Component
public class VoteService {
	
	@Autowired
    private ISysUserService sysUserService;
	
	@Autowired
	private IWqVoteService wqVoteService;
	
	@Autowired
    private WxMsgService wxMsgService;
	
    @Autowired
	private RedisCache redisCache;
    
    public final static String KEY_SCORE = "key:score";
    
	public final static String KEY_USER = "key:user";

	public void saveVote(WqVoteVO wqVote) {
		if(StringUtils.isBlank(wqVote.getUid())){
			throw new ServiceException("缺少参数");
		}
		Boolean hasKey = redisCache.hasKey(wqVote.getUid());
		if(hasKey){
			Long uid = redisCache.incr(wqVote.getUid());
			if(uid < 2){
				SysUser user = sysUserService.getById(SecurityUtils.getUserId());
				// 每天只能发布一次
				QueryWrapper<WqVote> queryWrapper = new QueryWrapper<>();
				WqVote entity = new WqVote();
				entity.setUserId(user.getUserId());
				queryWrapper.setEntity(entity);
				WqVote vote = wqVoteService.getOne(queryWrapper);
				if(vote != null){
					if(vote.getCreateTime().compareTo(DateUtils.getDayYesterday()) > 0){
						throw new ServiceException("今天已经发布",888);
					}
				}
				
				if(user.getVoteNum() < 1){
					// 会员可以免费申请
					if(user.getVipEndTime() == null){
						throw new ServiceException("只对会员开放，请开通会员",788);
					}
				}else{
					// 消耗次数
					user.setVoteNum(0);
					sysUserService.updateById(user);
				}
				
				wqVote.setNickName(user.getNickName());
				wqVote.setCity(user.getCity());
				wqVote.setUserId(user.getUserId());
				wqVote.setAvatar(user.getAvatar());
				wqVote.setVoteNum(0L);
				wqVoteService.save(wqVote);
				
				// 删除昨天的
				QueryWrapper<WqVote> qw = new QueryWrapper<>();
				qw.le("create_time", DateUtils.getDayYesterday());
				List<WqVote> voteList = wqVoteService.list(qw);
				if(voteList != null && voteList.size()>0){
					redisCache.deleteObject("voteScore");
					redisCache.deleteObject("voteMapScore");
				}
				wqVoteService.remove(qw);
			}
			redisCache.deleteObject(wqVote.getUid());
		}
	}

	public void addVote(WqVoteVO wqVote) {
		SysUser sysUser = sysUserService.getById(SecurityUtils.getUserId());
		if(StringUtils.isBlank(sysUser.getSex())){
			throw new ServiceException("请选择性别", 521);
		}
		
		sysUser.setIsDog("0");
		sysUser.setGameTime(wqVote.getGameTime());
		sysUserService.updateById(sysUser);
		
		WqVoteVO vote = new WqVoteVO();
		vote.setUserId(sysUser.getUserId());
		vote.setNickName(sysUser.getNickName());
		vote.setAvatar(sysUser.getAvatar());
		vote.setCity(sysUser.getCity());
		vote.setIsShow(sysUser.getIsShow());
		vote.setGameTime(wqVote.getGameTime());
		
		redisCache.zadd(KEY_SCORE, String.valueOf(sysUser.getUserId()), wqVote.getGameTime());
		// 把前200名的用户存进缓存
		long rank = redisCache.zrank(KEY_SCORE, String.valueOf(sysUser.getUserId()));
		wqVote.setCityRank(rank);
		if(rank < 20){
			// 前20名赠送一天会员
			if(sysUser.getVipEndTime() == null || sysUser.getVipEndTime().compareTo(new Date()) < 0){
				Date vipStartTime = new Date();
				Date vipEndTime = DateUtil.offsetDay(vipStartTime, 1);
				sysUser.setWechatNum(10);
				sysUser.setPublishNum(3);
				sysUser.setVipStartTime(vipStartTime);
				sysUser.setVipEndTime(vipEndTime);
				sysUserService.updateById(sysUser);
				
				// 挑战成功
				WxMaMsgForm form = new WxMaMsgForm();
				form.setAppId(sysUser.getAppId());
				form.setOpenId(sysUser.getOpenId());
				Map<String,String> map = new HashMap<>();
				map.put("phrase1", "反馈通知");
				map.put("date2", DateUtil.now());
				map.put("name3", "反应速度测试");
				map.put("thing4", "挑战成功！进入前20名");
				form.setDataMap(map);
				form.setPage("/packgeMine/pages/game/rank?my=true");
				wxMsgService.sendSubscribeMsg(form);
			}
		}
		if(rank < 200){
			redisCache.setCacheMapValue(KEY_USER, String.valueOf(sysUser.getUserId()), vote);
		}
	}

	public List<WqVoteVO> getVoteList(WqVoteVO wqVote) {
		IPage<WqVoteVO> pageBean = Condition.getPage(wqVote);
		long current = pageBean.getCurrent();
		Set<String> userIds = redisCache.zrange(KEY_SCORE, 0, 9);
		if(current > 1){
			userIds = redisCache.zrange(KEY_SCORE, 10, 99);
		}
		List<WqVoteVO> voteList = new ArrayList<WqVoteVO>();
		for(String userId : userIds){
			WqVoteVO vote = redisCache.getCacheMapValue(KEY_USER, userId);
			voteList.add(vote);
		}
		return voteList;
	}

	public WqVoteVO getVoteByUserId(Long userId) {
		WqVoteVO vote = new WqVoteVO();
		if(userId == null || userId < 1){
			vote.setGameTime(9.999d);
			vote.setCityRank(99999L);
			vote.setIsRank(false);
			return vote;
		}
		Double gameTime = redisCache.zscore(KEY_SCORE, String.valueOf(userId));
		Long rank = redisCache.zrank(KEY_SCORE, String.valueOf(userId));
		if(rank == null){
			vote.setGameTime(9.999d);
			vote.setCityRank(99999L);
			vote.setIsRank(false);
			return vote;
		}
		vote.setCityRank(rank+1);
		vote.setGameTime(gameTime);
		if(rank < 100){
			vote.setIsRank(false);
		}else{
			Set<String> userIds = redisCache.zrange(KEY_SCORE, 99, 99);
			Double time = redisCache.zscore(KEY_SCORE, String.valueOf(userIds.iterator().next()));
			vote.setRankTime(gameTime-time);
			vote.setIsRank(true);
		}
		return vote;
	}

}
